home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / LINEconsole / mtas.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  22.8 KB  |  1,090 lines

  1. /* mtas.c: mta routines */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/LINEconsole/RCS/mtas.c,v 6.0 1991/12/18 20:26:30 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/LINEconsole/RCS/mtas.c,v 6.0 1991/12/18 20:26:30 jpo Rel $
  9.  *
  10.  * $Log: mtas.c,v $
  11.  * Revision 6.0  1991/12/18  20:26:30  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16. #include    "console.h"
  17.  
  18. char    *mta_match = NULLCP;
  19. int    mta_num_matches = 0;
  20. struct mta_struct    **mta_matches = NULL;
  21.  
  22. extern int    connected;
  23. extern struct procStatus    *create_status();
  24. extern struct chan_struct    *currentchan, *find_channel();
  25. extern char    *time_t2RFC(), *vol2str(), *time_t2str(), *cmd_argv[],
  26.         *itoa(), *mystrtotime();
  27. extern int total_number_reports, total_number_messages, total_volume, compat, 
  28.     cmd_argc;
  29.  
  30. #define     MTA_READ_INTERVAL    60    /* in secs */
  31.  
  32. extern struct msg_struct    **global_msg_list;
  33. extern int        number_msgs;
  34.  
  35. static void display_mta_list();
  36. static void update_mta_list();
  37. static struct mta_struct **create_mta_list();
  38. static struct mta_struct *create_mta();
  39.  
  40. extern Level lev;
  41. extern int info_shown;
  42.  
  43. struct mta_struct    *currentmta = NULL, *find_mta();
  44.  
  45. /* ARGSUSED */
  46. int do_mtaread (ad, ds, args, arg)
  47. int                ad;
  48. struct client_dispatch        *ds;
  49. char                **args; /* args[0] is channel name */
  50. struct type_Qmgr_MtaRead    **arg;
  51. {
  52.     char    *str;
  53.     UTC    utc;
  54.  
  55.     *arg = (struct type_Qmgr_MtaRead *) malloc(sizeof(**arg));
  56.     utc = (UTC) malloc (sizeof(struct UTCtime));
  57.  
  58.     utc->ut_flags = UT_SEC;
  59.     utc->ut_sec = MTA_READ_INTERVAL;
  60.     str = utct2str(utc);
  61.     (*arg)->time = str2qb(str, strlen(str), 1);
  62.  
  63.     (*arg)->channel = str2qb(args[0],
  64.                  strlen(args[0]),
  65.                  1);
  66. }
  67.  
  68.  
  69. /* ARGSUSED */
  70. int mtaread_result (ad, id, dummy, result, roi)
  71. int                        ad,
  72.                         id,
  73.                         dummy;
  74. register struct type_Qmgr_PrioritisedMtaList    *result;
  75. struct RoSAPindication                *roi;
  76. {
  77.  
  78.     struct chan_struct    *chan = currentchan;
  79.     
  80.     
  81.     free_mta_list(&(chan->mtalist), &(chan->num_mtas));
  82.     chan->mtalist = NULL;
  83.     chan->num_mtas = 0;
  84.     if (result != NULL)
  85.         update_mta_list(result, chan);
  86.     else
  87.         update_channel_from_mtas(chan, 0, 0, 0, 0);
  88.     order_mtas(&(chan->mtalist),chan->num_mtas);
  89.     return OK;
  90. }
  91.  
  92. mta_list()
  93. {
  94.     if (connected == TRUE && currentchan != NULL) {
  95.         my_invoke(mtaread, &(currentchan->channelname));
  96.         display_mta_list(currentchan);
  97.     }
  98. }
  99.  
  100. mta_do_refresh ()
  101. {
  102.     if (connected == TRUE) {
  103.         channel_do_refresh();
  104.         if (currentchan != NULL) {
  105.             my_invoke(mtaread, &(currentchan->channelname));
  106.             if (mta_match) 
  107.                 find_mta_regex(currentchan, mta_match);
  108.             reset_prompt_regex();
  109.  
  110.             if (lev == mta) {
  111.                 if (mta_num_matches > 0 && info_shown == TRUE)
  112.                     mta_info_regex();
  113.                 else
  114.                     display_mta_list(currentchan);
  115.             }
  116.         }
  117.     }
  118. }
  119.                     
  120. /*   */    
  121.  
  122. clear_mta_level()
  123. {
  124.     if (currentchan) {
  125.         free_mta_list(&(currentchan->mtalist), &(currentchan->num_mtas));
  126.         currentchan->mtalist = NULL;
  127.         currentchan->num_mtas = 0;
  128.     }
  129.     currentmta = NULL;
  130. }
  131.  
  132. free_mta_list(plist, pnum)
  133. struct mta_struct    ***plist;
  134. int            *pnum;
  135. {
  136.     int    i = 0;
  137.  
  138.     while(i < (*pnum)){
  139.         if ((*plist) [i] != NULL) {
  140.             free((*plist)[i]->mta);
  141.             if ((*plist)[i]->info != NULLCP)
  142.                 free((*plist)[i] -> info);
  143.             free((char *) (*plist)[i]->status);
  144.         }
  145.         i++;
  146.     }
  147.     if (*plist != NULL)
  148.         free((char *) (*plist));
  149.     *plist = NULL;
  150.     *pnum = 0;
  151. }
  152.  
  153. static void update_mta_list(new, chan)
  154. struct type_Qmgr_PrioritisedMtaList    *new;
  155. struct chan_struct            *chan;
  156. {
  157.     int                    numberMsgs = 0,
  158.                         numberDrs = 0,
  159.                         numberMtas = 0,
  160.                         volume = 0;
  161.     chan->mtalist = create_mta_list(new,&numberMtas,
  162.                     &numberDrs,&numberMsgs,&volume,
  163.                     chan);
  164.     update_channel_from_mtas(chan, numberMsgs, numberDrs, numberMtas, volume);
  165. }
  166.  
  167. static struct mta_struct    **create_mta_list(list, pnum, pdr, pmsgnum, pvolume, chan)
  168. struct type_Qmgr_PrioritisedMtaList    *list;
  169. int                    *pnum,
  170.                       *pdr,
  171.                     *pmsgnum,
  172.                     *pvolume;
  173. struct chan_struct            *chan;
  174. {
  175.     struct type_Qmgr_PrioritisedMtaList     *ix = list;
  176.     struct mta_struct            **mtalist;
  177.     int                    i;
  178.     while (ix != NULL) {
  179.         (*pnum)++;
  180.  
  181.         ix = ix->next;
  182.     }
  183.     
  184.     mtalist = (struct mta_struct    **) calloc( (unsigned)(*pnum), 
  185.                            sizeof(struct mta_struct *));
  186.  
  187.     ix = list;
  188.     i = 0;
  189.     *pmsgnum = 0;
  190.     *pdr = 0;
  191.  
  192.     while ((ix != NULL)
  193.            && ( i < (*pnum))) {
  194.         mtalist[i] = create_mta(ix->PrioritisedMta, chan);
  195.         *pmsgnum += mtalist[i]->numberMessages;
  196.         *pdr += mtalist[i]->numberReports;
  197.         *pvolume += mtalist[i]->volumeMessages;
  198.         i++;
  199.         ix = ix->next;
  200.     }
  201.     return mtalist;
  202. }
  203.  
  204. static struct mta_struct    *create_mta(themta, chan)
  205. struct type_Qmgr_PrioritisedMta    *themta;
  206. struct chan_struct        *chan;
  207. {
  208.     struct mta_struct        *temp;
  209.     struct type_Qmgr_MtaInfo    *info = themta->mta;
  210.  
  211.     temp = (struct mta_struct *) malloc(sizeof(*temp));
  212.  
  213.     temp->mta = qb2str(info->mta);
  214.     temp->oldestMessage = convert_time(info->oldestMessage);
  215.     temp->numberMessages = info->numberMessage;
  216.     temp->numberReports = info->numberDRs;
  217.     temp->volumeMessages = info->volumeMessages;
  218.     temp->status = create_status(info->status);
  219.     temp->priority = themta->priority->parm;
  220.     temp->active = info->active;
  221.     if (info -> info != NULL)
  222.         temp -> info = qb2str(info -> info);
  223.     else
  224.         temp -> info = NULLCP;
  225.     add_tailor_to_mta(chan, temp);
  226.     return temp;
  227. }
  228.  
  229. update_mta(old, info)
  230. struct mta_struct            *old;
  231. struct type_Qmgr_MtaInfo        *info;
  232. {
  233.     /* name doesn't change */
  234.     old->oldestMessage = convert_time(info->oldestMessage);
  235.     old->numberMessages = info->numberMessage;
  236.     old->numberReports = info->numberDRs;
  237.     old->volumeMessages = info->volumeMessages;
  238.     old->active = info->active;
  239.     if (old -> info) 
  240.         free (old -> info);
  241.     if (info -> info != NULL)
  242.         old -> info = qb2str(info -> info);
  243.     else
  244.         old -> info = NULLCP;
  245.     update_status(old->status,info->status);
  246. }
  247.  
  248. update_channel_from_mtas(chan, nmsgs, ndrs, nmtas, volume)
  249. struct chan_struct    *chan;
  250. int            nmsgs,
  251.               ndrs,
  252.             nmtas,
  253.             volume;
  254. {
  255.     int    changed = FALSE;
  256.     
  257.     if (chan -> numberMessages != nmsgs) {
  258.         if (compat)
  259.             total_number_messages 
  260.                 += nmsgs - chan -> numberMessages;
  261.         chan -> numberMessages = nmsgs;
  262.         changed = TRUE;
  263.     }
  264.     
  265.     if (chan -> numberReports != ndrs) {
  266.         if (compat)
  267.             total_number_reports += ndrs - chan -> numberReports;
  268.         chan -> numberReports = ndrs;
  269.         changed = TRUE;
  270.     }
  271.  
  272.     if (chan -> num_mtas != nmtas) {
  273.         chan -> num_mtas = nmtas;
  274.         changed = TRUE;
  275.     }
  276.     if (chan -> volumeMessages != volume) {
  277.         if (compat)
  278.             total_volume += volume - chan -> volumeMessages;
  279.         chan -> volumeMessages = volume;
  280.         changed = TRUE;
  281.     }
  282.  
  283.     if (chan->given_num_mtas != chan -> num_mtas) {
  284.         chan -> given_num_mtas = chan->num_mtas;
  285.         changed = TRUE;
  286.     }
  287. }
  288.  
  289.  
  290. /*   */
  291. extern int uk_order;
  292. extern char    *reverse_mta();
  293. extern FILE    *out;
  294.  
  295. static void display_mta(mta)
  296. struct mta_struct    *mta;
  297. {
  298.     char    str[BUFSIZ];
  299.     char    *ch;
  300.  
  301.     ch = (uk_order)? reverse_mta(mta->mta) : mta->mta;
  302.     sprintf(str, "%s %s: %d",ch, 
  303.         (mta -> active) ? "(ACTIVE)" : "",
  304.         mta->numberMessages);
  305.     if (uk_order && ch != mta->mta) free(ch);
  306.     if (mta->numberReports != 0)
  307.       sprintf(str, "%s + %d", str, mta->numberReports);
  308.     if (mta->status->enabled != TRUE)
  309.         sprintf(str, "%s (DISABLED)", str);
  310.     fprintf(out, "%s\n", str);
  311. }
  312.  
  313. display_mta_info(chan,mta)
  314. struct chan_struct    *chan;
  315. struct mta_struct    *mta;
  316. {
  317.     char        *str,
  318.             *info_str,
  319.             *ch;
  320.     int        info_strlen = BUFSIZ;
  321.     char        tmpbuf[BUFSIZ];
  322.     info_str = calloc(1, (unsigned) info_strlen);
  323.  
  324.     ch = (uk_order) ? reverse_mta(mta->mta) : mta->mta;
  325.     
  326.     sprintf(tmpbuf, "on channel '%s'", chan->channelname);
  327.     sprintf(info_str, ssformat, tab,
  328.         ch, tmpbuf);
  329.  
  330.     if (uk_order && ch != mta->mta)
  331.         free(ch);
  332.  
  333.     if (mta->status->cachedUntil != 0) {
  334.         str = time_t2RFC(mta->status->cachedUntil);
  335.         sprintf(info_str, plus_ssformat, info_str, tab,
  336.             "delayed until",
  337.             str);
  338.         free(str);
  339.     }
  340.     if (mta->info != NULLCP)
  341.         sprintf (info_str, plus_ssformat, info_str, tab,
  342.              "error info",
  343.              mta -> info);
  344.     
  345.     str = time_t2str(time((time_t *) 0) - mta->oldestMessage);
  346.     sprintf(info_str, plus_ssformat, info_str, tab,
  347.         "oldest message",
  348.         str);
  349.     free(str);
  350.  
  351.     str = itoa(mta->numberMessages);
  352.     sprintf(info_str, plus_ssformat, info_str, tab,
  353.         "number of messages",
  354.         str);
  355.     free(str);
  356.  
  357.     if (mta->numberReports != 0) {
  358.       str = itoa(mta->numberReports);
  359.       sprintf(info_str, plus_ssformat, info_str, tab,
  360.           "number of drs",
  361.           str);
  362.       free(str);
  363.     }
  364.  
  365.     str = vol2str(mta->volumeMessages);
  366.     sprintf(info_str, plus_ssformat, info_str, tab,
  367.         "volume of messages",
  368.         str);
  369.     free(str);
  370.  
  371.     if (mta -> active) 
  372.         sprintf(info_str, plus_ssformat, info_str, tab,
  373.             "active",
  374.             "processes running");
  375.  
  376.     sprintf(info_str, plus_ssformat, info_str, tab,
  377.         "status",
  378.         (mta->status->enabled == TRUE) ? "enabled" : "disabled");
  379.     if (mta->status->lastAttempt != 0) {
  380.         str = time_t2RFC(mta->status->lastAttempt);
  381.         sprintf(info_str, plus_ssformat, info_str, tab,
  382.             "last attempt",
  383.             str);
  384.         free(str);
  385.     }
  386.     if (mta->status->lastSuccess != 0) {
  387.         str = time_t2RFC(mta->status->lastSuccess);
  388.         sprintf(info_str, plus_ssformat, info_str, tab,
  389.             "last success",
  390.             str);
  391.         free(str);
  392.     }
  393.  
  394.     switch (mta->priority) {
  395.         case int_Qmgr_Priority_low:
  396.         sprintf(info_str, plus_ssformat, info_str, tab,
  397.             "priority",
  398.             "low");
  399.         break;
  400.         case int_Qmgr_Priority_normal:
  401.         sprintf(info_str, plus_ssformat, info_str, tab,
  402.             "priority",
  403.             "normal");
  404.         break;
  405.         case int_Qmgr_Priority_high:
  406.         sprintf(info_str, plus_ssformat, info_str, tab,
  407.             "priority",
  408.             "high");
  409.         break;
  410.         default:
  411.         break;
  412.     }
  413.  
  414.     fprintf(out, "%s", info_str);
  415.     free(info_str);
  416. }
  417.  
  418. mta_info_regex()
  419. {
  420.     int    i;
  421.     if (currentchan && mta_num_matches > 0) {
  422.         openpager();
  423.         if (mta_num_matches > 1)
  424.             fprintf(out, "%s: %d matches\n\n",
  425.                 mta_match, mta_num_matches);
  426.         for (i = 0; i < mta_num_matches; i++) {
  427.             display_mta_info(currentchan, mta_matches[i]);
  428.             fprintf(out, "\n");
  429.         }
  430.         closepager();
  431.     }
  432. }
  433.  
  434. static void display_mta_list(chan)
  435. struct chan_struct    *chan;
  436. {
  437.     int    i;
  438.     
  439.     openpager();
  440.  
  441.     for (i = 0; i < chan->num_mtas; i++)
  442.         display_mta(chan->mtalist[i]);
  443.     closepager();
  444. }
  445.  
  446. /*   */
  447.  
  448. struct mta_struct    *find_mta(chan, name)
  449. struct chan_struct    *chan;
  450. char            *name;
  451. {
  452.     int    i = 0;
  453.     while ((i < chan->num_mtas) &&
  454.            (strcmp(chan->mtalist[i]->mta, name) != 0))
  455.         i++;
  456.     if (i >= chan->num_mtas)
  457.         return NULL;
  458.     else
  459.         return chan->mtalist[i];
  460. }    
  461.  
  462. extern char    *re_comp();
  463. extern int    re_exec();
  464.  
  465. int find_mta_regex(chan, name)
  466. struct chan_struct    *chan;
  467. char            *name;
  468. {
  469.     int    i = 0;
  470.     char    *diag;
  471.  
  472.     if ((diag = re_comp(name)) != 0) {
  473.         fprintf(stderr,
  474.             "re_comp error for '%s' [%s]\n", name, diag);
  475.         return 0;
  476.     }
  477.  
  478.     if (mta_matches) {
  479.         free(mta_matches);
  480.         mta_matches = NULL;
  481.     }
  482.     mta_matches = (struct mta_struct **) calloc(chan->num_mtas,
  483.                             sizeof(struct mta_struct *));
  484.  
  485.     for (i = 0, mta_num_matches = 0; i < chan->num_mtas; i++)
  486.         if (re_exec(lowerfy(chan->mtalist[i]->mta)) == 1)
  487.             mta_matches[mta_num_matches++] = chan->mtalist[i];
  488.  
  489.     return mta_num_matches;
  490. }    
  491.  
  492. mta_set_current_regex()
  493. {
  494.     int    cont = TRUE, quit = FALSE, first = TRUE;
  495.     char    buf[BUFSIZ];
  496.  
  497.     while (cont == TRUE) {
  498.         if (cmd_argc > 1 && first == TRUE) {
  499.             strcpy(buf, cmd_argv[1]);
  500.             first = FALSE;
  501.         } else {
  502.             fprintf(stdout, "match expression (%s) (q=quit) = ", 
  503.                 (mta_match == NULLCP) ? "" : mta_match);
  504.             fflush(stdout);
  505.  
  506.             if (gets(buf) == NULL)
  507.                 exit (OK);
  508.         }
  509.         compress(buf, buf);
  510.         
  511.         if (emptyStr(buf) && mta_match == NULLCP)
  512.             fprintf(stdout, "no match set\n");
  513.         else {
  514.             if (!emptyStr(buf)) {
  515.                 if (lexequ(buf, "q") != 0) {
  516.                     if (mta_match) free(mta_match);
  517.                     mta_match = strdup(buf);
  518.                 } else
  519.                     quit = TRUE;
  520.             }
  521.             cont = FALSE;
  522.         }
  523.     }
  524.     if (quit == TRUE)
  525.         return NOTOK;
  526.     if (find_mta_regex(currentchan, mta_match) == 0) {
  527.         fprintf(stdout, "unable to find match for '%s'\n",
  528.             mta_match);
  529.         return NOTOK;
  530.     }
  531.     return OK;
  532. }
  533.  
  534. mta_set_current()
  535. {
  536.     int    cont = TRUE, i, quit = FALSE, first = TRUE;
  537.     char    buf[BUFSIZ];
  538.  
  539.     if (currentchan == NULL)
  540.         channel_set_current();
  541.  
  542.     while (cont == TRUE) {
  543.         if (cmd_argc > 1 && first == TRUE) {
  544.             strcpy(buf, cmd_argv[1]);
  545.             first = FALSE;
  546.         } else {
  547.             fprintf(stdout, "match expression (%s) (q=quit) = ", 
  548.                 (mta_match == NULL) ? "" : mta_match);
  549.             fflush(stdout);
  550.  
  551.             if (gets(buf) == NULL)
  552.                 exit (OK);
  553.         }
  554.         compress(buf, buf);
  555.  
  556.         if (emptyStr(buf) && mta_match == NULLCP)
  557.             fprintf(stdout, "no match set\n");
  558.         else if (!emptyStr(buf) && lexequ(buf, "q") == 0) {
  559.             quit = TRUE;
  560.             cont = FALSE;
  561.         } else {
  562.             char    *exp = (emptyStr(buf)) ? mta_match : buf;
  563.             int num = find_mta_regex(currentchan, exp);
  564.             switch (num) {
  565.                 case 0:
  566.                 fprintf(stdout, "unable to find match for '%s'\n", exp);
  567.                 break;
  568.                 case 1:
  569.                 cont = FALSE;
  570.                 if (exp != mta_match) {
  571.                     if (mta_match) free(mta_match);
  572.                     mta_match = strdup(exp);
  573.                 }
  574.                 currentmta = mta_matches[0];
  575.                 break;
  576.                 default:
  577.                 fprintf(stdout, "'%s' matches %d possible mtas (",
  578.                     exp, num);
  579.                 for (i = 0; i < num; i++)
  580.                     fprintf(stdout, "%s%s",
  581.                         mta_matches[i]->mta,
  582.                         (i == num -1) ? "" : ",");
  583.                 fprintf(stdout, ")\n\tneed unqiue mta\n");
  584.                 break;
  585.             }
  586.         }
  587.     }
  588.     if (quit == TRUE)
  589.         return NOTOK;
  590.     return OK;
  591. }
  592.  
  593.  
  594. /*   */
  595.  
  596. mta_next ()
  597. {
  598.     if (currentchan && currentchan -> num_mtas > 0) {
  599.         int    i = 0;
  600.         if (mta_num_matches > 0) {
  601.             while (i < currentchan -> num_mtas &&
  602.                    currentchan->mtalist[i] != mta_matches[0])
  603.                 i++;
  604.             if (i >= currentchan -> num_mtas - 1)
  605.                 i = 0;
  606.             else
  607.                 i++;
  608.         }
  609.         if (mta_match) free(mta_match);
  610.         mta_match = strdup(currentchan->mtalist[i]->mta);
  611.         find_mta_regex(currentchan, mta_match);
  612.     }
  613. }
  614.  
  615. mta_previous ()
  616. {
  617.     if (currentchan && currentchan -> num_mtas > 0) {
  618.         int    i = currentchan -> num_mtas - 1;
  619.         if (mta_num_matches > 0) {
  620.             while (i >= 0 &&
  621.                    currentchan->mtalist[i] != mta_matches[0])
  622.                 i--;
  623.             if (i <= 0)
  624.                 i = currentchan -> num_mtas - 1;
  625.             else
  626.                 i--;
  627.         }
  628.         if (mta_match) free(mta_match);
  629.         mta_match = strdup(currentchan -> mtalist[i]-> mta);
  630.         find_mta_regex(currentchan, mta_match);
  631.     }
  632. }
  633.  
  634. /*   */
  635.  
  636.  
  637. mta_control(op, chan, mta, mytime)
  638. Operations    op;
  639. char        *chan, *mta, *mytime;
  640. {
  641.     char    *args[4];
  642.     args[0] = chan;
  643.     args[1] = mta;
  644.     args[2] = (char *) op;
  645.     args[3] = mytime;
  646.     my_invoke(op, args);
  647. }
  648.  
  649. mta_enable_regex()
  650. {
  651.     int    cont, i = 0;
  652.     char    buf[BUFSIZ];
  653.     
  654.     if (currentchan && mta_num_matches > 0) {
  655.         if (mta_num_matches > 1)
  656.             fprintf(stdout, "%s: %d matches\n\n",
  657.                 mta_match, mta_num_matches);
  658.         for (i = 0; i < mta_num_matches; i++) {
  659.             cont = TRUE;
  660.             while (cont == TRUE) {
  661.                 if (mta_num_matches == 1) {
  662.                     fprintf(stdout, "enabling '%s'.\n",
  663.                         mta_matches[i]->mta);
  664.                     buf[0] = 'y';
  665.                 } else {
  666.                     fprintf(stdout, "enable '%s' (y/n/q) ?",
  667.                         mta_matches[i]->mta);
  668.                     fflush(stdout);
  669.                     if (gets(buf) == NULL)
  670.                         exit(OK);
  671.                     compress(buf, buf);
  672.                 }
  673.                 switch(buf[0]) {
  674.                     case 'y':
  675.                     case 'Y':
  676.                     mta_control(mtastart,
  677.                             currentchan->channelname,
  678.                             mta_matches[i]->mta,
  679.                             NULLCP);
  680.                     case 'n':
  681.                     case 'N':
  682.                     cont = FALSE;
  683.                     break;
  684.                     case 'q':
  685.                     case 'Q':
  686.                     cont = FALSE;
  687.                     i = mta_num_matches;
  688.                     default:
  689.                     break;
  690.                 }
  691.             }
  692.         }
  693.     }
  694. }
  695.  
  696. mta_disable_regex()
  697. {
  698.     int    cont, i = 0;
  699.     char    buf[BUFSIZ];
  700.     
  701.     if (currentchan && mta_num_matches > 0) {
  702.         if (mta_num_matches > 1)
  703.             fprintf(stdout, "%s: %d matches\n\n",
  704.                 mta_match, mta_num_matches);
  705.         for (i = 0; i < mta_num_matches; i++) {
  706.             cont = TRUE;
  707.             while (cont == TRUE) {
  708.                 if (mta_num_matches == 1) {
  709.                     fprintf(stdout, "disabling '%s'.\n",
  710.                         mta_matches[i]->mta);
  711.                     buf[0] = 'y';
  712.                 } else {
  713.                     fprintf(stdout, "disable '%s' (y/n/q) ?",
  714.                         mta_matches[i]->mta);
  715.                     fflush(stdout);
  716.                     if (gets(buf) == NULL)
  717.                         exit(OK);
  718.                     compress(buf, buf);
  719.                 }
  720.                 switch(buf[0]) {
  721.                     case 'y':
  722.                     case 'Y':
  723.                     mta_control(mtastop,
  724.                             currentchan->channelname,
  725.                             mta_matches[i]->mta,
  726.                             NULLCP);
  727.                     case 'n':
  728.                     case 'N':
  729.                     cont = FALSE;
  730.                     break;
  731.                     case 'q':
  732.                     case 'Q':
  733.                     cont = FALSE;
  734.                     i = mta_num_matches;
  735.                     default:
  736.                     break;
  737.                 }
  738.             }
  739.         }
  740.     }
  741. }
  742.  
  743. mta_clear_regex()
  744. {
  745.     int    cont, i = 0;
  746.     char    buf[BUFSIZ];
  747.     
  748.     if (currentchan && mta_num_matches > 0) {
  749.         if (mta_num_matches > 1)
  750.             fprintf(stdout, "%s: %d matches\n\n",
  751.                 mta_match, mta_num_matches);
  752.         for (i = 0; i < mta_num_matches; i++) {
  753.             cont = TRUE;
  754.             while (cont == TRUE) {
  755.                 if (mta_num_matches == 1) {
  756.                     fprintf(stdout, "clearing '%s'.\n",
  757.                         mta_matches[i]->mta);
  758.                     buf[0] = 'y';
  759.                 } else {
  760.                     fprintf(stdout, "clear '%s' (y/n/q) ?",
  761.                         mta_matches[i]->mta);
  762.                     fflush(stdout);
  763.                     if (gets(buf) == NULL)
  764.                         exit(OK);
  765.                     compress(buf, buf);
  766.                 }
  767.                 switch(buf[0]) {
  768.                     case 'y':
  769.                     case 'Y':
  770.                     mta_control(mtaclear,
  771.                             currentchan->channelname,
  772.                             mta_matches[i]->mta,
  773.                             NULLCP);
  774.                     case 'n':
  775.                     case 'N':
  776.                     cont = FALSE;
  777.                     break;
  778.                     case 'q':
  779.                     case 'Q':
  780.                     cont = FALSE;
  781.                     i = mta_num_matches;
  782.                     default:
  783.                     break;
  784.                 }
  785.             }
  786.         }
  787.     }
  788. }
  789.  
  790. mta_force (chan, mta)
  791. struct chan_struct    *chan;
  792. struct mta_struct    *mta;
  793. {
  794.     if (mta->status->enabled != TRUE)
  795.         mta_control(mtastart, chan->channelname, 
  796.                 mta->mta, NULLCP);
  797.     if (mta->status->cachedUntil != 0)
  798.         mta_control(mtaclear, chan->channelname,
  799.                 mta->mta, NULLCP);
  800.  
  801. }
  802.  
  803. mta_clear_below_regex()
  804. {
  805.     int    cont, i = 0;
  806.     char    buf[BUFSIZ];
  807.     
  808.     if (currentchan && mta_num_matches > 0) {
  809.         if (mta_num_matches > 1)
  810.             fprintf(stdout, "%s: %d matches\n\n",
  811.                 mta_match, mta_num_matches);
  812.         for (i = 0; i < mta_num_matches; i++) {
  813.             cont = TRUE;
  814.             while (cont == TRUE) {
  815.                 if (mta_num_matches == 1) {
  816.                     fprintf(stdout, "clearing entities below '%s'.\n",
  817.                         mta_matches[i]->mta);
  818.                     buf[0] = 'y';
  819.                 } else {
  820.                     fprintf(stdout, "clear entities below '%s' (y/n/q) ?",
  821.                         mta_matches[i]->mta);
  822.                     if (gets(buf) == NULL)
  823.                         exit(OK);
  824.                     compress(buf, buf);
  825.                 }
  826.                 switch(buf[0]) {
  827.                     case 'y':
  828.                     case 'Y':
  829.                     mta_downforce(currentchan,
  830.                               mta_matches[i]);
  831.                     case 'n':
  832.                     case 'N':
  833.                     cont = FALSE;
  834.                     break;
  835.                     case 'q':
  836.                     case 'Q':
  837.                     cont = FALSE;
  838.                     i = mta_num_matches;
  839.                     default:
  840.                     break;
  841.                 }
  842.             }
  843.         }
  844.     }
  845. }
  846.  
  847. mta_clear_above_regex()
  848. {
  849.     int    cont, i = 0, above = FALSE;
  850.     char    buf[BUFSIZ];
  851.     
  852.     if (currentchan && mta_num_matches > 0) {
  853.         if (mta_num_matches > 1)
  854.             fprintf(stdout, "%s: %d matches\n\n",
  855.                 mta_match, mta_num_matches);
  856.         for (i = 0; i < mta_num_matches; i++) {
  857.             cont = TRUE;
  858.             while (cont == TRUE) {
  859.                 if (mta_num_matches == 1) {
  860.                     fprintf(stdout, "clearing entities above '%s'.\n",
  861.                         mta_matches[i]->mta);
  862.                     buf[0] = 'y';
  863.                 } else {
  864.                     fprintf(stdout, "clear entities above '%s' (y/n/q) ?",
  865.                         mta_matches[i]->mta);
  866.                     fflush(stdout);
  867.                     if (gets(buf) == NULL)
  868.                         exit(OK);
  869.                     compress(buf, buf);
  870.                 }
  871.                 switch(buf[0]) {
  872.                     case 'y':
  873.                     case 'Y':
  874.                     mta_force(currentchan,
  875.                           mta_matches[i]);
  876.                     above = TRUE;
  877.                     case 'n':
  878.                     case 'N':
  879.                     cont = FALSE;
  880.                     break;
  881.                     case 'q':
  882.                     case 'Q':
  883.                     cont = FALSE;
  884.                     i = mta_num_matches;
  885.                     default:
  886.                     break;
  887.                 }
  888.             }
  889.         }
  890.         if (above == TRUE)
  891.             channel_force(currentchan);
  892.  
  893.     }
  894. }
  895.  
  896. mta_downforce_list (chan)
  897. struct chan_struct    *chan;
  898. {
  899.     int    i;
  900.     for (i = 0; i < chan->num_mtas; i++)
  901.         mta_downforce(chan, chan->mtalist[i]);
  902. }
  903.     
  904. mta_downforce (chan, mta)
  905. struct chan_struct    *chan;
  906. struct mta_struct    *mta;
  907. {
  908.     struct msg_struct    **oldlist;
  909.     int    oldnum;
  910.     char    *args[2];
  911.  
  912.     args[0] = chan -> channelname;
  913.     args[1] = mta->mta;
  914.     oldlist = global_msg_list;
  915.     oldnum = number_msgs;
  916.     global_msg_list = NULL;
  917.     number_msgs = 0;
  918.     currentmta = mta;
  919.     my_invoke(readchannelmtamessage, args);
  920.     msg_force_list(global_msg_list);
  921.     currentmta = NULL;
  922.     free_msg_list();
  923.     global_msg_list = oldlist;
  924.     number_msgs = oldnum;
  925.  
  926.     mta_force(chan, mta);
  927. }
  928.  
  929. mta_delay_regex()
  930. {
  931.     int    dcont, cont, i = 0;
  932.     char    buf[BUFSIZ], delay[BUFSIZ];
  933.     delay[0] = '\0';
  934.     if (currentchan && mta_num_matches > 0) {
  935.         if (mta_num_matches > 1)
  936.             fprintf(stdout, "%s: %d matches\n\n",
  937.                 mta_match, mta_num_matches);
  938.         for (i = 0; i < mta_num_matches; i++) {
  939.             cont = TRUE;
  940.             while (cont == TRUE) {
  941.                 if (mta_num_matches == 1) {
  942.                     fprintf(stdout, "delaying '%s'.\n",
  943.                         mta_matches[i]->mta);
  944.                     buf[0] = 'y';
  945.                 } else {
  946.                     fprintf(stdout, "delay '%s' (y/n/q) ?",
  947.                         mta_matches[i]->mta);
  948.                     fflush(stdout);
  949.                     if (gets(buf) == NULL)
  950.                         exit(OK);
  951.                     compress(buf, buf);
  952.                 }
  953.                 switch(buf[0]) {
  954.                     case 'y':
  955.                     case 'Y':
  956.                     dcont = TRUE;
  957.                     while (dcont == TRUE) {
  958.                         fprintf(stdout, "Delay (in s m h d and/or w) [%s] = ");
  959.                         fflush(stdout);
  960.         
  961.                         if (gets(buf) == NULL)
  962.                             exit(OK);
  963.                         compress(buf, buf);
  964.                         
  965.                         if (emptyStr(buf)) {
  966.                             if (delay[0] != '\0')
  967.                                 /* happy with the one we got */
  968.                                 dcont = FALSE;
  969.                             else
  970.                                 fprintf(stdout, "no delay given\n");
  971.                         } else {
  972.                             dcont = FALSE;
  973.                             strcpy(delay, buf);
  974.                         }
  975.                     }
  976.                     mta_control(mtacacheadd, 
  977.                             currentchan->channelname,
  978.                             mta_matches[i]->mta, 
  979.                             delay);
  980.  
  981.                     case 'n':
  982.                     case 'N':
  983.                     cont = FALSE;
  984.                     break;
  985.                     case 'q':
  986.                     case 'Q':
  987.                     cont = FALSE;
  988.                     i = mta_num_matches;
  989.                     default:
  990.                     break;
  991.                 }
  992.             }
  993.         }
  994.     }
  995. }
  996.  
  997. /* ARGSUSED */
  998. int do_mtacontrol (ad, ds, args, arg)
  999. int                ad;
  1000. struct client_dispatch        *ds;
  1001. char                **args;
  1002. struct type_Qmgr_MtaControl    **arg;
  1003. /* args[0] = channel */
  1004. /* args[1] = mta */
  1005. /* args[2] = stop,start,clear,cacheadd */
  1006. /* args[3] = time */
  1007. {
  1008.     char    *timestr;
  1009.     *arg = (struct type_Qmgr_MtaControl *) malloc(sizeof(**arg));
  1010.     (*arg)->control = (struct type_Qmgr_Control *)
  1011.         malloc(sizeof(struct type_Qmgr_Control));
  1012.  
  1013.     (*arg)->channel = str2qb(args[0],
  1014.                  strlen(args[0]),
  1015.                  1);
  1016.     (*arg)->mta = str2qb(args[1],
  1017.                  strlen(args[1]),
  1018.                  1);
  1019.  
  1020.     switch ((Operations) args[2]) {
  1021.         case mtastart:
  1022.         (*arg)->control->offset = type_Qmgr_Control_start;
  1023.         break;
  1024.         case mtastop:
  1025.         (*arg)->control->offset = type_Qmgr_Control_stop;
  1026.         break;
  1027.         case mtaclear:
  1028.         (*arg)->control->offset = type_Qmgr_Control_cacheClear;
  1029.         break;
  1030.         case mtacacheadd:
  1031.         (*arg)->control->offset = type_Qmgr_Control_cacheAdd;
  1032.         timestr = mystrtotime(args[3]);
  1033.         (*arg)->control->un.cacheAdd = str2qb(timestr,strlen(timestr),1);
  1034.         free(timestr);
  1035.         break;
  1036.         default:
  1037.         PP_LOG(LLOG_EXCEPTIONS,
  1038.                ("console : '%s' unknown control param for mtas",
  1039.             args[2]));
  1040.         return NOTOK;
  1041.     }
  1042.     return OK;
  1043. }
  1044.  
  1045. /* ARGSUSED */
  1046. int mtacontrol_result (ad, id, dummy, result, roi)
  1047. int                        ad,
  1048.                         id,
  1049.                         dummy;
  1050. register struct type_Qmgr_MtaInfo        *result;
  1051. struct RoSAPindication                *roi;
  1052. {
  1053.     char            *chan_name,
  1054.                 *name;
  1055.     struct chan_struct    *chan;
  1056.     struct mta_struct    *mta;
  1057.  
  1058.     chan_name = qb2str(result->channel);
  1059.     chan = find_channel(chan_name);
  1060.  
  1061.     if (chan == NULL) {
  1062.         PP_LOG(LLOG_EXCEPTIONS,
  1063.                ("console: mtacontrol_result can't find channel %s",chan_name));
  1064.         return NOTOK;
  1065.     }
  1066.  
  1067.     name = qb2str(result->mta);
  1068.     mta = find_mta(chan, name);
  1069.  
  1070.     if (mta == NULL) {
  1071. #ifdef not_ipm_yet
  1072.         if (forceDown == TRUE) {
  1073.             free(chan_name);
  1074.             free(name);
  1075.             return OK;
  1076.         }
  1077. #endif
  1078.         PP_LOG(LLOG_EXCEPTIONS,
  1079.                ("console:can not find mta %s on channel %s", 
  1080.             name, chan_name));
  1081.         abort();
  1082.     } else {
  1083.         update_mta(mta,result);
  1084.     }
  1085.     order_mtas(&(chan->mtalist),chan->num_mtas);
  1086.     free(chan_name);
  1087.     free(name);
  1088.     return OK;
  1089. }
  1090.